package com.ruoyi.web.controller.jiekou;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONValidator;
import com.juhe.sdk.ApiClient;
import com.juhe.sdk.common.Result;
import com.juhe.sdk.reqeust.EnterpriseTaxQueryRequest;
import com.juhe.sdk.reqeust.StudentVerifyRequest;
import com.juhe.sdk.response.BankCardHVerifyResponse;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.AESUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.http.JuFaHttp;
import com.ruoyi.finance.domain.Account;
import com.ruoyi.finance.domain.AccountVO;
import com.ruoyi.finance.domain.ChargeRecord;
import com.ruoyi.finance.domain.Merchant;
import com.ruoyi.finance.mapper.ChargeRecordMapper;
import com.ruoyi.finance.mapper.MerchantMapper;
import com.ruoyi.finance.service.IMerchantService;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.jiekou.domain.InterPrice;
import com.ruoyi.jiekou.domain.JieKou;
import com.ruoyi.jiekou.domain.RequestDto;
import com.ruoyi.jiekou.mapper.CacheMapper;
import com.ruoyi.jiekou.mapper.InterPriceMapper;
import com.ruoyi.jiekou.mapper.JieKouMapper;
import com.ruoyi.jiekou.service.IInterPriceService;
import com.ruoyi.jiekou.service.IJieKouService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.ruoyi.common.constant.Constants.UTF8;
import static com.ruoyi.common.utils.DateUtils.YYYY_MM_DD_HH_MM_SS;
import static com.ruoyi.common.utils.DateUtils.parseDateToStr;
import static com.ruoyi.common.utils.http.HttpUtils.httpPostWitParamMap;
import static com.ruoyi.jiekou.service.impl.JieKouServiceImpl.*;

@Slf4j
@RestController
@RequestMapping("/jiekou")
public class JieKouController extends BaseController {

    @Autowired
    private IJieKouService jieKouService;

    @Autowired
    private IMerchantService iMerchantService;

    @Autowired
    private IInterPriceService iInterPriceService;

    @Autowired
    private InterPriceMapper interPriceMapper;

    @Autowired
    private JieKouMapper jieKouMapper;

    @Autowired
    private ChargeRecordMapper chargeRecordMapper;

    @Autowired
    private MerchantMapper merchantMapper;

    @Autowired
    private CacheMapper cacheMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 获取商户及其附带的接口信息
     */
    @GetMapping("/getSMAndInter")
    public TableDataInfo getSMAndInter(Account account) {
        startPage();
        List<AccountVO> accounts = merchantMapper.selectSMAndInter(account);
        List<JieKou> jieKous = jieKouMapper.selectJieKouList(null);
        List<String> jfCodes = jieKous.stream().map(JieKou::getJfCode).collect(Collectors.toList());
        for (AccountVO accountVO : accounts) {
            List<String> acojfCodes = accountVO.getIns().stream().map(InterPrice::getJfCode).collect(Collectors.toList());
            for (int i = 0; i < jfCodes.size(); i++) {
                String jsCode = jfCodes.get(i);
                if (!acojfCodes.contains(jsCode)) {
                    // 不包含此价格 使用原基础定价
                    JieKou jieKou = jieKous.get(i);
                    accountVO.getIns().add(new InterPrice(jieKou.getJfCode(), jieKou.getName(), jieKou.getUnitPrice()));
                }
            }
        }
        return getDataTable(accounts);
    }

    /**
     * 用户专属价格表
     */
    @GetMapping("/getUserInterInfo")
    public TableDataInfo getInterPrice(JieKou jk) {
        startPage();
        jk.setStatus("0");
        List<JieKou> jieKous = jieKouMapper.selectJieKouList(jk);
        if (jieKous.isEmpty()) {
            return getDataTable(jieKous);
        }
        List<String> jfCodes = jieKous.stream().map(JieKou::getJfCode).collect(Collectors.toList());
        List<InterPrice> interPriceList = interPriceMapper.selectInterPriceByIds(jfCodes, SecurityUtils.getLoginUser().getUserId());
        List<String> ipjfCodes = interPriceList.stream().map(InterPrice::getJfCode).collect(Collectors.toList());
        for (int i = 0; i < ipjfCodes.size(); i++) {
            int index = jfCodes.indexOf(ipjfCodes.get(i));
            jieKous.get(index).setUnitPrice(interPriceList.get(i).getPrice());
            jieKous.get(index).setDelFlag("1");
        }
        return getDataTable(jieKous);
    }

    /**
     * 远程商户专属价格表
     */
    @GetMapping("/getInterPriceByYanCheng")
    public BigDecimal getInterPriceByYanCheng(String[] jks, String mc) {
        List<JieKou> jieKous = jieKouMapper.selectJieKouByJKS(jks);
        List<String> jfCodes = jieKous.stream().map(JieKou::getJfCode).collect(Collectors.toList());
        List<InterPrice> interPriceList = interPriceMapper.selectInterPriceByMcs(jfCodes, mc);
        List<String> ipjfCodes = interPriceList.stream().map(InterPrice::getJfCode).collect(Collectors.toList());
        for (int i = 0; i < ipjfCodes.size(); i++) {
            int index = jfCodes.indexOf(ipjfCodes.get(i));
            jieKous.get(index).setUnitPrice(interPriceList.get(i).getPrice());
            jieKous.get(index).setDelFlag("1");
        }
        BigDecimal sum = new BigDecimal(0.0);
        for (JieKou jk : jieKous) {
            sum = sum.add(jk.getUnitPrice());
        }
        return sum;
    }

    /**
     * 修改此用户的每个接口价格
     */
    @GetMapping("/updaPrice")
    public AjaxResult updataInterPrice(InterPrice ip) {
        int i;
        if (ip.getId() != null) {    // 有专属定价
            i = iInterPriceService.updateInterPrice(new InterPrice(ip.getId(), ip.getPrice()));
        } else {     // 无专属定价
            i = iInterPriceService.insertInterPrice(ip);
        }
        return toAjax(i);
    }

    @GetMapping("/list")
    public TableDataInfo list(JieKou jieKou) {
        startPage();
        List<JieKou> list = jieKouService.selectJieKouList(jieKou);
        return getDataTable(list);
    }

    /**
     * 修改【接口信息】
     */
    @PutMapping
    public AjaxResult edit(@RequestBody JieKou jieKou) {
        return toAjax(jieKouService.updateJieKou(jieKou));
    }

    @GetMapping("/getJMeg")
    public void getJMeg(HttpServletResponse response) throws IOException {
        // 读取文件
        response.setCharacterEncoding("UTF-8");
        //设置显示文件的类型
        response.setContentType("application/txt;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName="
                + URLEncoder.encode("secrit.txt", "UTF-8"));
        ClassPathResource resource = new ClassPathResource("InterPDF/secrit.txt");
        InputStream in = resource.getInputStream();
        int count;
        byte[] by = new byte[1024];

        //通过response对象获取OutputStream流
        OutputStream out = response.getOutputStream();
        while ((count = in.read(by)) != -1) {
            out.write(by, 0, count);//将缓冲区的数据输出到浏览器
        }
        in.close();
        out.flush();
    }

    @Anonymous
    @GetMapping("/accredit/{code}")
    public void getAccredit(HttpServletResponse response, @PathVariable("code") String code) throws IOException {
        // 读取文件
        response.setCharacterEncoding("UTF-8");
        //设置显示文件的类型
        response.setContentType("application/docx;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName="
                + URLEncoder.encode("授权书" + code + ".docx", "UTF-8"));
        InputStream in = new FileInputStream("授权书" + code + ".docx");
        int count;
        byte[] by = new byte[1024];
        //通过response对象获取OutputStream流
        OutputStream out = response.getOutputStream();
        while ((count = in.read(by)) != -1) {
            out.write(by, 0, count);//将缓冲区的数据输出到浏览器
        }
        in.close();
        out.flush();
    }


    @GetMapping("/jieKouExcel")
    public void jieKouExcel(HttpServletResponse response, String name) throws IOException {
        // 读取文件
        response.setCharacterEncoding("UTF-8");
        //设置显示文件的类型
        response.setContentType("application/xlsx;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName="
                + URLEncoder.encode(name + ".xls", "UTF-8"));
        ClassPathResource resource = new ClassPathResource("InterPDF/" + name + ".xls");
        InputStream in = resource.getInputStream();
        int count;
        byte[] by = new byte[1024];
        //通过response对象获取OutputStream流
        OutputStream out = response.getOutputStream();
        while ((count = in.read(by)) != -1) {
            out.write(by, 0, count);//将缓冲区的数据输出到浏览器
        }
        in.close();
        out.flush();
    }

    @GetMapping("/export")
    public void export(HttpServletResponse response, JieKou jieKou) throws IOException {
        // 读取文件
        response.setCharacterEncoding("UTF-8");
        //设置显示文件的类型
        response.setContentType("application/pdf;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName="
                + URLEncoder.encode(jieKou.getName() + ".pdf", "UTF-8"));
        ClassPathResource resource = new ClassPathResource("InterPDF/" + jieKou.getName() + ".pdf");
        InputStream in = resource.getInputStream();
        int count = 0;
        byte[] by = new byte[1024];
        //通过response对象获取OutputStream流
        OutputStream out = response.getOutputStream();
        while ((count = in.read(by)) != -1) {
            out.write(by, 0, count);//将缓冲区的数据输出到浏览器
        }
        in.close();
        out.flush();
    }

    @Anonymous
    @GetMapping(value = "/{jfCode}")
    public AjaxResult getInfo(@PathVariable("id") String jfCode) {
        return success(jieKouService.selectJieKouByjfCode(jfCode));
    }

    /**
     * 密文查询数据
     */
    @PostMapping("/jufa")
    public JSONObject jufaEncryptSelect(HttpServletRequest http, @RequestBody RequestDto requestDto) {
        // 提取商户号
        JSONObject reJs = new JSONObject();

        if (StringUtils.isEmpty(requestDto.getRequest_sn())) {
            reJs.put("retcode", "4000");
            reJs.put("retmsg", "请建立商户侧查询单号并传送给聚法数据");
            return reJs;
        }

        String mc_code = http.getHeader("mccode");
        if (StringUtils.isEmpty(mc_code)) {
            reJs.put("retcode", "4001");
            reJs.put("retmsg", "请提供商户号");
            return reJs;
        }
        if (StringUtils.isEmpty(requestDto.getInter_id())) {
            reJs.put("retcode", "4002");
            reJs.put("retmsg", "无接口编号");
            return reJs;
        }
        // 同一个商户的连续密集并发请求要异步处理
        synchronized (this) {
            Merchant merchant = iMerchantService.selectMerchantByUserOne(new Merchant(mc_code));
            if (merchant == null) {
                reJs.put("retcode", "4003");
                reJs.put("retmsg", "商户号错误或禁用");
                return reJs;
            }
            // 提取接口编号，拉取扣费信息，预判收费
            JieKou jieKou = jieKouService.getUserInterPrice(mc_code, requestDto.getInter_id());
            if (jieKou == null) {
                reJs.put("retcode", "4004");
                reJs.put("retmsg", "接口编号错误");
                return reJs;
            } else if (jieKou.getUnitPrice().compareTo(merchant.getBalance()) == 1) {
                reJs.put("retcode", "4005");
                reJs.put("retmsg", "余额不足");
                return reJs;
            }
            // 参数转换
            JSONObject req_params;
            try {
                if (StringUtils.isEmpty(requestDto.getReq_params())) {
                    reJs.put("retcode", "4006");
                    reJs.put("retmsg", "无加密的业务参数");
                    return reJs;
                }
                // 解码解密查询参数
                String decrypt = AESUtils.decryptByHexString(requestDto.getReq_params(), merchant.getSecretKey());
                req_params = JSONObject.parse(decrypt);
            } catch (Exception e) {
                e.printStackTrace();
                reJs.put("retcode", "4006");
                reJs.put("retmsg", "接口业务参数解密失败，请检查核验");
                return reJs;
            }
            // 提取关键字下发查询
            reJs = jieKouService.select(req_params, merchant, jieKou, requestDto.getRequest_sn());
            // 对数据加密
            String retdata;
            if ("000000".equals(reJs.getString("retcode"))) {
                // 查询成功，数据加密
                JSONValidator validator = JSONValidator.from(reJs.getString("retdata"));
                JSONValidator.Type jsonType = validator.getType();
                if (jsonType == JSONValidator.Type.Object) {
                    retdata = reJs.getJSONObject("retdata").toJSONString();
                } else if (jsonType == JSONValidator.Type.Array) {
                    retdata = reJs.getJSONArray("retdata").toJSONString();
                } else {
                    retdata = reJs.getString("retdata");
                }
                reJs.replace("retdata", AESUtils.encryptIntoHexString(retdata, merchant.getSecretKey()));
            } else if (jieKou.getSourceTypeNum() == 3) {
                retdata = reJs.getJSONObject("retdata").toJSONString();
                reJs.replace("retdata", AESUtils.encryptIntoHexString(retdata, merchant.getSecretKey()));
            }
            return reJs;
        }
    }

    /**
     * 明文查询数据
     */
    @Anonymous
    @PostMapping("/jufaAndi")
    public JSONObject jufaByAndiSelect(HttpServletRequest http, @RequestBody JSONObject req_params) {
        log.info("明文查询参数：" + req_params);
        JSONObject reJs = new JSONObject();
        String requestSn = req_params.getString("request_sn");
        if (StringUtils.isEmpty(requestSn)) {
            reJs.put("retcode", "4000");
            reJs.put("retmsg", "请建立商户侧查询单号并传送给聚法数据");
            return reJs;
        }
        String mccode = http.getHeader("mccode");
        if (StringUtils.isEmpty(mccode)) {
            reJs.put("retcode", "4001");
            reJs.put("retmsg", "请提供商户号");
            return reJs;
        }
        Merchant merchant = merchantMapper.selectMerchantPrice(mccode);
        if (merchant == null) {
            reJs.put("retcode", "4003");
            reJs.put("retmsg", "商户号错误/或禁用");
            return reJs;
        }
        String interId = req_params.getString("inter_id");
        if (StringUtils.isEmpty(interId)) {
            reJs.put("retcode", "4002");
            reJs.put("retmsg", "无接口编号");
            return reJs;
        }
        String[] inters = {interId};
        BigDecimal yanCheng = getInterPriceByYanCheng(inters, mccode);
        if (yanCheng == null) {
            reJs.put("retcode", "4004");
            reJs.put("retmsg", "接口编号错误");
            return reJs;
        }
        if (merchant.getBalance().floatValue() < yanCheng.floatValue()) {
            reJs.put("retcode", "4005");
            reJs.put("retmsg", "余额不足");
            return reJs;
        }
        JieKou jieKou = jieKouService.getUserInterPrice(merchant.getMerchantCode(), interId);
        reJs = jieKouService.select(req_params, merchant, jieKou, requestSn);
        return reJs;
    }

    /**
     * 明文查询数据
     */
    @Anonymous
    @PostMapping("/overall")
    public JSONObject jufaOverall(HttpServletRequest http, @RequestBody JSONObject req_params) {
        log.info("overall查询参数：" + req_params);
        JSONObject reJs = new JSONObject();
        String requestSn = req_params.getString("request_sn");
        if (StringUtils.isEmpty(requestSn)) {
            reJs.put("retcode", "4000");
            reJs.put("retmsg", "无查询单号");
            return reJs;
        }
        String mccode = http.getHeader("mccode");
        if (StringUtils.isEmpty(mccode)) {
            reJs.put("retcode", "4001");
            reJs.put("retmsg", "请提供商户号");
            return reJs;
        }
        Merchant merchant = merchantMapper.selectMerchantPrice(mccode);
        if (merchant == null) {
            reJs.put("retcode", "4003");
            reJs.put("retmsg", "商户号错误或禁用");
            return reJs;
        }
        JieKou jieKou = jieKouService.getUserInterPrice(merchant.getMerchantCode(), "JF034");
        BigDecimal yanCheng = jieKou.getUnitPrice();
        if (yanCheng == null) {
            reJs.put("retcode", "4004");
            reJs.put("retmsg", "接口编号错误");
            return reJs;
        }
        if (merchant.getBalance().floatValue() < yanCheng.floatValue()) {
            reJs.put("retcode", "4005");
            reJs.put("retmsg", "余额不足");
            return reJs;
        }
        if (!req_params.containsKey("name")) {
            reJs.put("retcode", "4006");
            reJs.put("retmsg", "缺少姓名参数");
            return reJs;
        }
        if (!req_params.containsKey("card_no")) {
            reJs.put("retcode", "4007");
            reJs.put("retmsg", "缺少身份证参数");
            return reJs;
        }
        if (!req_params.containsKey("mobile")) {
            reJs.put("retcode", "4008");
            reJs.put("retmsg", "缺少电话号码参数");
            return reJs;
        }
        reJs = jieKouService.queryOverall(req_params, jieKou, merchant);
        return reJs;
    }

    /**
     * 聚法全维度报告
     */
    @Anonymous
    @PostMapping("/report")
    public JSONObject jufaReport(HttpServletRequest http, @RequestBody JSONObject req_params) {
        log.info("明文查询参数：" + req_params);
        JSONObject reJs = new JSONObject();
        String requestSn = req_params.getString("request_sn");
        if (StringUtils.isEmpty(requestSn)) {
            reJs.put("retcode", "4000");
            reJs.put("retmsg", "缺少商户侧查询单号");
            return reJs;
        }
        ChargeRecord record = new ChargeRecord();
        record.setRequestSn(requestSn);
        List<ChargeRecord> chargeRecords = chargeRecordMapper.selectChargeRecordList(record);
        if (!chargeRecords.isEmpty()) {
            reJs.put("retcode", "4007");
            reJs.put("retmsg", "单号重复（request_sn）");
            return reJs;
        }
        String mccode = http.getHeader("mccode");
        if (StringUtils.isEmpty(mccode)) {
            reJs.put("retcode", "4001");
            reJs.put("retmsg", "请提供商户号");
            return reJs;
        }
        Merchant merchant = merchantMapper.selectMerchantPrice(mccode);
        if (merchant == null) {
            reJs.put("retcode", "4003");
            reJs.put("retmsg", "商户号错误/禁用");
            return reJs;
        }
        String interId = req_params.getString("inter_id");
        if (StringUtils.isEmpty(interId)) {
            reJs.put("retcode", "4002");
            reJs.put("retmsg", "无接口编号");
            return reJs;
        }
        String[] inters = {interId};
        BigDecimal yanCheng = getInterPriceByYanCheng(inters, mccode);
        if (yanCheng == null) {
            reJs.put("retcode", "4004");
            reJs.put("retmsg", "接口编号错误");
            return reJs;
        }
        if (merchant.getBalance().floatValue() < yanCheng.floatValue()) {
            reJs.put("retcode", "4005");
            reJs.put("retmsg", "余额不足");
            return reJs;
        }
        JieKou jieKou = jieKouService.getUserInterPrice(merchant.getMerchantCode(), interId);
        StringBuffer keyWord = new StringBuffer();
        if (!req_params.containsKey("cardNo") || !req_params.containsKey("name") || !req_params.containsKey("mobile")) {
            reJs.put("retcode", "4006");
            reJs.put("retmsg", "缺少三要素");
            return reJs;
        } else {
            keyWord.append(req_params.getString("cardNo")).append("::" + req_params.getString("name")).append("::" + req_params.getString("mobile"));
        }
        BigDecimal subtract = merchant.getBalance().subtract(jieKou.getUnitPrice());
        ChargeRecord cr = new ChargeRecord(merchant.getMerchantCode(), requestSn, jieKou.getName(), keyWord.toString(), jieKou.getUnitPrice(), subtract);
        iMerchantService.debit(new Merchant(merchant.getMerchantCode(), jieKou.getUnitPrice()), cr);

        reJs.put("retcode", "000000");
        reJs.put("returl", "https://jiekou.funishe.com/report?ID=" + cr.getId());
        return reJs;
    }

    @Anonymous
    @PostMapping("/black")
    public JSONObject black(HttpServletRequest http, @RequestBody JSONObject req_params) {
        log.info("明文查询参数：" + req_params);
        JSONObject reJs = new JSONObject();
        String requestSn = req_params.getString("request_sn");
        if (StringUtils.isEmpty(requestSn)) {
            reJs.put("retcode", "4000");
            reJs.put("retmsg", "缺少商户侧查询单号");
            return reJs;
        }
        ChargeRecord record = new ChargeRecord();
        record.setRequestSn(requestSn);
        List<ChargeRecord> chargeRecords = chargeRecordMapper.selectChargeRecordList(record);
        if (!chargeRecords.isEmpty()) {
            reJs.put("retcode", "4007");
            reJs.put("retmsg", "单号重复（request_sn）");
            return reJs;
        }
        String mccode = http.getHeader("mccode");
        if (StringUtils.isEmpty(mccode)) {
            reJs.put("retcode", "4001");
            reJs.put("retmsg", "请提供商户号");
            return reJs;
        }
        Merchant merchant = merchantMapper.selectMerchantPrice(mccode);
        if (merchant == null) {
            reJs.put("retcode", "4003");
            reJs.put("retmsg", "商户号错误/禁用");
            return reJs;
        }
        String interId = req_params.getString("inter_id");
        if (StringUtils.isEmpty(interId)) {
            reJs.put("retcode", "4002");
            reJs.put("retmsg", "无接口编号");
            return reJs;
        }
        String[] inters = {interId};
        BigDecimal yanCheng = getInterPriceByYanCheng(inters, mccode);
        if (yanCheng == null) {
            reJs.put("retcode", "4004");
            reJs.put("retmsg", "接口编号错误");
            return reJs;
        }
        if (merchant.getBalance().floatValue() < yanCheng.floatValue()) {
            reJs.put("retcode", "4005");
            reJs.put("retmsg", "余额不足");
            return reJs;
        }
        JieKou jieKou = jieKouService.getUserInterPrice(merchant.getMerchantCode(), interId);
        StringBuffer keyWord = new StringBuffer();
        if (req_params.containsKey("card_no") && req_params.containsKey("name") && req_params.containsKey("mobile")) {
            keyWord.append(req_params.getString("card_no")).
                    append("::" + req_params.getString("name")).
                    append("::" + req_params.getString("mobile"));
        } else {
            reJs.put("retcode", "4006");
            reJs.put("retmsg", "三要素缺失");
            return reJs;
        }
        BigDecimal subtract = merchant.getBalance().subtract(jieKou.getUnitPrice());
        ChargeRecord cr = new ChargeRecord(merchant.getMerchantCode(), requestSn, jieKou.getName(), keyWord.toString(), jieKou.getUnitPrice(), subtract);
        iMerchantService.debit(new Merchant(merchant.getMerchantCode(), jieKou.getUnitPrice()), cr);

        reJs.put("retcode", "000000");
        reJs.put("returl", "https://jiekou.funishe.com/report?ID=" + cr.getId());
        JSONObject blackQuery = jieKouService.blackQuery(req_params);
        reJs.putAll(blackQuery);
        chargeRecordMapper.updateChargeRecord(new ChargeRecord(cr.getId(), reJs.toJSONString()));
        return reJs;
    }


    @Anonymous
    @GetMapping("/hmd")
    public Object wlzphmd(@NotNull Integer ID) {
        ChargeRecord cr = chargeRecordMapper.selectChargeRecordById(ID);
        if (cr == null || !("江苏定制报告".equals(cr.getInterName()))) {
            return warn("无此订单");
        }
        JSONObject object = JSON.parseObject(cr.getQueryResult());
        String keyword = cr.getInterKeyword();
        String[] split = keyword.split("::");

        String cardNo = split[0];
        String name = split[1];
        String mobile = split[2];

        if (StringUtils.isNotEmpty(name)) {
            object.put("name", "**" + name.substring(1));
        } else {
            object.put("name", "");
        }
        if (StringUtils.isNotEmpty(cardNo)) {
            object.put("cardNo", "***" + cardNo.substring(6));
        } else {
            object.put("cardNo", "");
        }
        if (StringUtils.isNotEmpty(mobile)) {
            object.put("mobile", "***" + mobile.substring(7));
        } else {
            object.put("mobile", "");
        }
        return object;
    }

    /**
     * 聚法全维度报告
     */
    @Anonymous
    @GetMapping("/reportData")
    public AjaxResult reportData(@NotNull Integer ID, @NotNull String type) throws Exception {
        ChargeRecord cr = chargeRecordMapper.selectChargeRecordById(ID);
        if (cr == null) {
            return warn("无此订单");
        } else if ("江苏定制报告".equals(cr.getInterName()) || "天启全维度报告".equals(cr.getInterName())) {
            String keyword = cr.getInterKeyword();
            String[] split = keyword.split("::");
            Map<String, Object> YS = new HashMap<>();
            YS.put("cardNo", split[0]);
            YS.put("name", split[1]);
            YS.put("mobile", split[2]);
            // 多头
            JSONObject data = null;
            String sn = cr.getRequestSn();
            if ("sjsys".equals(type)) {
                String value = cacheMapper.selectCache("JF007::" + keyword);
                if (StringUtils.isEmpty(value)) {
                    JSONObject ncmParams = new JSONObject();
                    ncmParams.put("name", split[1]);
                    ncmParams.put("cardNo", split[0]);
                    ncmParams.put("mobile", split[2]);
                    ncmParams.put("request_sn", cr.getRequestSn());
                    data = jieKouService.beiBuWan(new JieKou("vast-base/v3/base3"), ncmParams, "JF081" + keyword, "sjsys" + ID);
                    data = jieKouService.disposeBeiBuWan(data, cr.getRequestSn(), true);
                    data = jieKouService.beiBuWanThreeEleConversion(data);
                    cacheMapper.insertCache("JF081::" + keyword, data.toJSONString());
                } else {
                    data = JSON.parseObject(value);
                }
            } else if ("jxzs".equals(type)) {
                String value = cacheMapper.selectCache("JF010::" + keyword);
                if (StringUtils.isEmpty(value)) {
                    data = disposeYuShanReturnData(jieKouService.yuShan(YS, "JF010" + keyword, "RIS015", sn + "JF010"), true);
                    cacheMapper.insertCache("JF010::" + keyword, data.toJSONString());
                } else {
                    data = JSON.parseObject(value);
                }
            } else if ("dttz".equals(type)) {
                String value = cacheMapper.selectCache("JF011::" + keyword);
                if (StringUtils.isEmpty(value)) {
                    data = disposeBaiRongReturnData(jieKouService.baiRong(YS, "JF011::" + keyword, sn + "JF011"), sn, false);
                    cacheMapper.insertCache("JF011::" + keyword, data.toJSONString());
                } else {
                    data = JSON.parseObject(value);
                }
            } else if ("grss".equals(type)) {
                StudentVerifyRequest param = new StudentVerifyRequest();
                param.setIdCardNo(split[0]);
                param.setFullName(split[1]);
                try {
                    String value = cacheMapper.selectCache("JF025::" + keyword);
                    if (StringUtils.isEmpty(value)) {
                        data = disposeJuHeReturnData(jieKouService.juHe(new JieKou("A2"), param, "JF025::" + split[0] + "::" + split[1]), sn, false);
                        cacheMapper.insertCache("JF025::" + keyword, data.toJSONString());
                    } else {
                        data = JSON.parseObject(value);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else if ("wlzpsl".equals(type)) {
                data = new JSONObject();
                int cl = split[0].length();
                String name_ = "";
                try {
                    name_ = URLEncoder.encode(split[1], UTF8);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                String param = "name=" + name_ + "&cardNo=" + split[0].substring(cl - 6, cl);
                String s = HttpUtils.sendGet("http://175.178.170.139:8093/system/black/inter?" + param);
                JSONArray array = JSON.parseArray(s);
                data.put("hit", !array.isEmpty());
                data.put("hitData", array);
            }
            YS.put("time", parseDateToStr(YYYY_MM_DD_HH_MM_SS, cr.getChargeTime()));
            YS.put("data", data);
            if (StringUtils.isNotEmpty(YS.get("name").toString())) {
                YS.replace("name", "**" + YS.get("name").toString().substring(1));
            }
            if (StringUtils.isNotEmpty(YS.get("cardNo").toString())) {
                YS.replace("cardNo", "******" + YS.get("cardNo").toString().substring(6));
            }
            if (StringUtils.isNotEmpty(YS.get("mobile").toString())) {
                YS.replace("mobile", "*******" + YS.get("mobile").toString().substring(7));
            }
            return success(YS);
        } else {
            return warn("无此订单");
        }
    }

    @Anonymous
    @PostMapping("/wlhmd")
    public JSONObject wlhmd(HttpServletRequest http, @RequestBody JSONObject req_params) {
        log.info("明文查询参数：" + req_params);
        JSONObject reJs = new JSONObject();
        String requestSn = req_params.getString("request_sn");
        if (StringUtils.isEmpty(requestSn)) {
            reJs.put("retcode", "4000");
            reJs.put("retmsg", "缺少商户侧查询单号");
            return reJs;
        }
        ChargeRecord record = new ChargeRecord();
        record.setRequestSn(requestSn);
        List<ChargeRecord> chargeRecords = chargeRecordMapper.selectChargeRecordList(record);
        if (!chargeRecords.isEmpty()) {
            reJs.put("retcode", "4007");
            reJs.put("retmsg", "单号重复（request_sn）");
            return reJs;
        }
        String mccode = http.getHeader("mccode");
        if (StringUtils.isEmpty(mccode)) {
            reJs.put("retcode", "4001");
            reJs.put("retmsg", "请提供商户号");
            return reJs;
        }
        Merchant merchant = merchantMapper.selectMerchantPrice(mccode);
        if (merchant == null) {
            reJs.put("retcode", "4003");
            reJs.put("retmsg", "商户号错误/禁用");
            return reJs;
        }
        String[] inters = {"JF091"};
        BigDecimal yanCheng = getInterPriceByYanCheng(inters, mccode);
        if (yanCheng == null) {
            reJs.put("retcode", "4004");
            reJs.put("retmsg", "接口编号错误");
            return reJs;
        }
        if (merchant.getBalance().floatValue() < yanCheng.floatValue()) {
            reJs.put("retcode", "4005");
            reJs.put("retmsg", "余额不足");
            return reJs;
        }
        JieKou jieKou = jieKouService.getUserInterPrice(merchant.getMerchantCode(), "JF091");
        StringBuffer keyWord = new StringBuffer();
        if (req_params.containsKey("card_no") && req_params.containsKey("name")) {
            keyWord.append(req_params.getString("card_no")).
                    append("::" + req_params.getString("name"));
        } else {
            reJs.put("retcode", "4006");
            reJs.put("retmsg", "二要素缺失");
            return reJs;
        }
        BigDecimal subtract = merchant.getBalance().subtract(jieKou.getUnitPrice());
        ChargeRecord cr = new ChargeRecord(merchant.getMerchantCode(), requestSn, jieKou.getName(), keyWord.toString(), jieKou.getUnitPrice(), subtract);
        iMerchantService.debit(new Merchant(merchant.getMerchantCode(), jieKou.getUnitPrice()), cr);

        JSONObject object = new JSONObject();
        String name = req_params.getString("name");
        String cardNo = req_params.getString("card_no");
        int cl = cardNo.length();
        String name_ = "";
        try {
            name_ = URLEncoder.encode(name, UTF8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String param = "name=" + name_ + "&cardNo=" + cardNo.substring(cl - 6, cl);
        String s = HttpUtils.sendGet("http://175.178.170.139:8093/system/black/inter?" + param);
        JSONArray array = JSON.parseArray(s);
        object.put("hit", !array.isEmpty());
        object.put("hitData", array);
        return object;
    }

    /**
     * 查询企业纳税报告采集状态
     */
    @Anonymous
    @GetMapping("/qtrs")
    public AjaxResult queryTaxReportStatus(String taskId) {
        //提供的接口根路径 url
        String url = "https://api.shoohe.com/customer-api";
        //您的 appId
        String appId = "1000003020240626";
        //您的 appSecret
        String apiSecret = "ofSgvvRDQE7b2wwcPBAEFAK5Y8MC2Vg6";
        //1.准备客户端
        ApiClient apiClient = new ApiClient(url, appId, apiSecret);
        //2.准备参数
        EnterpriseTaxQueryRequest param = new EnterpriseTaxQueryRequest();
        param.setTaskId(taskId);
        try {
            Result<BankCardHVerifyResponse> response = apiClient.queryReportResult(param);
            if (response.getCode() != 200) {
                log.error("调用出错： {}", JSONObject.toJSONString(response));
                return warn(JSONObject.toJSONString(response));
            }
            return success(response.getData());
            //后续业务处理
        } catch (Exception e) {
            log.error("调用出错: {}", e);
            return error(e.getMessage());
        }
    }

    /**
     * 查看企业纳税信息
     *
     * @return
     */
    @Anonymous
    @GetMapping("/comInfo")
    public AjaxResult comInfo(String requestSn) {
        if (StringUtils.isEmpty(requestSn)) {
            return AjaxResult.error("单号为空");
        }
        ChargeRecord com = chargeRecordMapper.selectCom(requestSn);
        JSONObject result = JSON.parseObject(com.getQueryResult());
        if (result.containsKey("reportNo")) {
            return success(result);
        }
        String retcode = result.getString("retcode");
        if (!"000000".equals(retcode)) {
            return AjaxResult.error("异常！", result);
        }
        //提供的接口根路径 url
        String url = "http://101.132.253.231/api";
        //您的 appId
        String appId = "1000003020240626";
        //您的 appSecret
        String apiSecret = "ofSgvvRDQE7b2wwcPBAEFAK5Y8MC2Vg6";
        //1.准备客户端
        ApiClient apiClient = new ApiClient(url, appId, apiSecret);
        //2.准备参数
        EnterpriseTaxQueryRequest param = new EnterpriseTaxQueryRequest();
        param.setTaskId(result.getJSONObject("retdata").getString("taskId"));        // 第 3 步返回的 taskId
        try {
            Result<com.alibaba.fastjson.JSONObject> response = apiClient.queryTaxReport(param);
            if (response.getCode() != 200) {
                log.error("调用出错： {}", response);
                return AjaxResult.error("调用出错： {}", response);
            } else {
                com.alibaba.fastjson.JSONObject data_ = response.getData();
                com.setInterKeyword(com.getInterKeyword() + "::" + data_.getString("companyName") + "::" + data_.getString("taxId"));
                com.setQueryResult(data_.toJSONString());
                chargeRecordMapper.updateChargeRecord(com);
                return success(data_);
            }
        } catch (Exception e) {
            log.error("调用出错: {}", e);
            return null;
        }
    }

    /**
     * 征信回调数据
     */
    @Anonymous
    @PostMapping("/creditCallBack")
    public void creditCallBack(@RequestParam Map<String, Object> params) {
        log.info("征信回调数据: " + params);
        // 启用异步处理
        AsyncManager.me().execute(new TimerTask() {
            @SneakyThrows
            @Override
            public void run() {
                String order_no = params.get("order_no").toString();
                String callBackUrl = redisTemplate.boundValueOps(order_no).get();
                int reqNum = 2;
                for (int i = 0; i < reqNum; i++) {
                    if (httpPostWitParamMap(callBackUrl, params)) {
                        break;
                    } else if (i + 1 != reqNum) {
                        TimeUnit.SECONDS.sleep(15);  // 15秒后再试一次
                    }
                }
            }
        });
    }

    /**
     * 主动获取征信数据
     */
    @Anonymous
    @GetMapping("/getCreditData")
    public JSONObject getCreditData(String type, String orderNo) throws Exception {
        JSONObject redisRes = JSONObject.parseObject(redisTemplate.boundValueOps("credit::" + orderNo).get());
        if (redisRes != null) {
            return redisRes;
        }
        JSONObject json = new JSONObject();
        json.put("token", "735822815bb64dd79f114b489213cd3c");
        json.put("timestamp", System.currentTimeMillis() + "");
        json.put("trans_id", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + RandomStringUtils.randomNumeric(16));
        JSONObject data = new JSONObject();
        data.put("order_no", orderNo);
        data.put("type", type);
        String aes = JuFaHttp.encrypt("pFeNMTyFhNRzHrCtNPzc25S7HxtSaR3j", "6KJAG1ZJF63K161E66S3D7ZHN52NHFB5".substring(0, 16), data.toString());
        json.put("data", aes);
        String receive = JuFaHttp.send("https://www.zewubeidiao.com:8087/dataMiddle/api/credit/res", json);
        log.info("主动获取征信数据: " + receive);
        JSONObject receiveJs = JSONObject.parseObject(receive);
        if (receiveJs.getInteger("code") == 0) {
            redisTemplate.boundValueOps("credit::" + orderNo).set(receiveJs.toJSONString(), 7, TimeUnit.DAYS);
        }
        return receiveJs;
    }

}
